package org.knowm.xchange.deribit.v2;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.knowm.xchange.BaseExchange;
import org.knowm.xchange.ExchangeSpecification;
import org.knowm.xchange.currency.Currency;
import org.knowm.xchange.deribit.v2.dto.marketdata.DeribitCurrency;
import org.knowm.xchange.deribit.v2.dto.marketdata.DeribitInstrument;
import org.knowm.xchange.deribit.v2.service.DeribitAccountService;
import org.knowm.xchange.deribit.v2.service.DeribitMarketDataService;
import org.knowm.xchange.deribit.v2.service.DeribitMarketDataServiceRaw;
import org.knowm.xchange.deribit.v2.service.DeribitTradeService;
import org.knowm.xchange.dto.meta.CurrencyMetaData;
import org.knowm.xchange.dto.meta.InstrumentMetaData;
import org.knowm.xchange.instrument.Instrument;

public class DeribitExchange extends BaseExchange {

  @Override
  public void applySpecification(ExchangeSpecification exchangeSpecification) {

    super.applySpecification(exchangeSpecification);
  }

  @Override
  protected void initServices() {
    this.marketDataService = new DeribitMarketDataService(this);
    this.accountService = new DeribitAccountService(this);
    this.tradeService = new DeribitTradeService(this);
  }

  @Override
  public ExchangeSpecification getDefaultExchangeSpecification() {

    ExchangeSpecification exchangeSpecification = new ExchangeSpecification(this.getClass());
    exchangeSpecification.setSslUri("https://www.deribit.com");
    exchangeSpecification.setHost("deribit.com");
    //    exchangeSpecification.setPort(80);
    exchangeSpecification.setExchangeName("Deribit");
    exchangeSpecification.setExchangeDescription("Deribit is a Bitcoin futures exchange");
    return exchangeSpecification;
  }

  public ExchangeSpecification getSandboxExchangeSpecification() {

    ExchangeSpecification exchangeSpecification = new ExchangeSpecification(this.getClass());
    exchangeSpecification.setSslUri("https://test.deribit.com/");
    exchangeSpecification.setHost("test.deribit.com");
    //    exchangeSpecification.setPort(80);
    return exchangeSpecification;
  }

  @Override
  public void remoteInit() throws IOException {
    updateExchangeMetaData();
  }

  public void updateExchangeMetaData() throws IOException {

    Map<Currency, CurrencyMetaData> currencies = exchangeMetaData.getCurrencies();
    Map<Instrument, InstrumentMetaData> instruments = exchangeMetaData.getInstruments();

    List<DeribitCurrency> activeDeribitCurrencies =
        ((DeribitMarketDataServiceRaw) marketDataService).getDeribitCurrencies();

    currencies.clear();
    instruments.clear();

    for (DeribitCurrency deribitCurrency : activeDeribitCurrencies) {
      currencies.put(
          new Currency(deribitCurrency.getCurrency()), DeribitAdapters.adaptMeta(deribitCurrency));
    }

      List<DeribitInstrument> deribitInstruments =
          ((DeribitMarketDataServiceRaw) marketDataService)
              .getDeribitInstruments(null, null, null);

    for (DeribitInstrument deribitInstrument : deribitInstruments) {
      var instrument = DeribitAdapters.toInstrument(deribitInstrument);

      if (instrument != null) {
        DeribitAdapters.putSymbolMapping(deribitInstrument.getInstrumentName(), instrument);
        instruments.put(instrument, DeribitAdapters.adaptMeta(deribitInstrument));
      }

    }
  }
}
